<?php
class RequestHelper extends YucyAbsHelper
{
    const SCHEME_HTTP  = 'http';

    const SCHEME_HTTPS = 'https';
    
    const GET = 'GET';
    
    const POST = 'POST';
    
	private $_requestUri = '';
	
	private $_baseUrl = '';
	
	private $_basePath = '';
	
	private $_pathInfo = '';
	
	private $_params = array();
	
	private static $_instance = null;
	
	
	public function __construct(){}
	
	
	public static function factory()
	{
		if (!self::$_instance) self::$_instance = new self;
		return self::$_instance;
	}
	
	
 	public function __get($name)
    {
        switch (true) 
        {
            case isset($this->_params[$name]):return $this->_params[$name];
            case isset($_GET[$name]):return $_GET[$name];
            case isset($_POST[$name]):return $_POST[$name];
            case isset($_COOKIE[$name]):return $_COOKIE[$name];
            case ($name == 'REQUEST_URI'):return $this->getRequestUri();
            case ($name == 'PATH_INFO'):return $this->getPathInfo();
            case isset($_SERVER[$name]):return $_SERVER[$name];
            case isset($_ENV[$name]):return $_ENV[$name];
            default:return null;
        }
    }
    
    
    /**
     * 
     * 获得请求的参数值
     * @param string $name
     */
	public function get($name)
    {
        return $this->__get($name);
    }
    
    
	public function __isset($name)
    {
        switch (true) 
        {
            case isset($this->_params[$name]):return true;
            case isset($_GET[$name]):return true;
            case isset($_POST[$name]):return true;
            case isset($_COOKIE[$name]): return true;
            case isset($_SERVER[$name]):return true;
            case isset($_ENV[$name]):return true;
            default:return false;
        }
    }

    
    /**
     * 
     * 是否存在某个参数
     * @param string $name
     */
    public function has($name)
    {
        return $this->__isset($name);
    }
    
    
    /**
     * 
     * 设置参数
     * @param string $name
     * @param mixed $value
     */
    public function setParameter($name, $value)
    {
        $this->_params[(string)$name] = $value;
        
        return $this;
    }
    
    
    /**
     * 
     * 获得参数的值
     * @param string $name
     * @param mixed $default
     */
    public function getParameter($name, $default = null)
    {
    	if (isset($this->_params[$name])) return $this->_params[$name];
    	
    	if (isset($_GET[$name])) return $_GET[$name];
    	
    	if (isset($_POST[$name])) return $_POST[$name];
    	
    	return $default;
    }
    
    
    /**
     * 
     * 返回所有参数信息
     */
	public function getParameters()
    {
        $params = $this->_params;
        
        if (isset($_GET) && is_array($_GET)) $params += $_GET;
        
        if (isset($_POST) && is_array($_POST)) $params += $_POST;
        
        return $params;
    }
    
    
    /**
     * 
     * 获得GET参数
     * @param string $name
     * @param mixed $default
     * @return mixed
     */
    public function getQuery($name = null, $default = null)
    {
        if ($name === null) return $_GET;

        return (isset($_GET[$name])) ? $_GET[$name] : $default;
    }
    
    
    /**
     * 
     * 设置GET参数
     * @param string $name
     * @param mixed $value
     * @return object
     */
    public function setQuery($name, $value)
    {
    	$_GET[(string)$name] = $value;
    	return $this;
    }
    
    
	public function getPost($name = null, $default = null)
    {
        if ($name === null) return $_POST;

        return (isset($_POST[$name])) ? $_POST[$name] : $default;
    }
    
    
    public function setPost($name, $value)
    {
    	$_POST[(string)$name] = $value;
    	return $this;
    }
    
    
	public function getCookie($name = null, $default = null)
    {
        if ($name === null) return $_COOKIE;

        return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $default;
    }
    
    
	public function getServer($name = null, $default = null)
    {
        if ($name === null) return $_SERVER;

        return (isset($_SERVER[$name])) ? $_SERVER[$name] : $default;
    }
    
    
	public function getEnv($name = null, $default = null)
    {
        if ($name === null) return $_ENV;

        return (isset($_ENV[$name])) ? $_ENV[$name] : $default;
    }
    
    
    public function getMethod()
    {
        return strtoupper($this->getServer('REQUEST_METHOD'));
    }
    
    
	public function getScheme()
    {
        return ($this->getServer('HTTPS') == 'on') ? self::SCHEME_HTTPS : self::SCHEME_HTTP;
    }
    
    
    public function isPost()
    {
    	return self::POST == $this->getMethod() ? true : false;
    }
    
    
    public function isGet()
    {
    	return self::GET == $this->getMethod() ? true : false;
    }
    
    
    public function isSecure()
    {
        return ($this->getScheme() === self::SCHEME_HTTPS);
    }
    
    
    public function isXMLHttpRequest()
    {
    	return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest');
    }
    
    
	public function getHttpHost()
    {
        $host = $this->getServer('HTTP_HOST');
        if (!empty($host)) return $host;

        $scheme = $this->getScheme();
        $name = $this->getServer('SERVER_NAME');
        $port = $this->getServer('SERVER_PORT');

        if (($scheme == self::SCHEME_HTTP && $port == 80) || ($scheme == self::SCHEME_HTTPS && $port == 443)) 
        {
            return $name;
        }
        
        return $name . ':' . $port;
    }
    
    
    /**
     * 
     * 获得请求的IP地址
     * @param bool $checkProxy
     */
	public function getClientIp($checkProxy = true)
    {
        if ($checkProxy && $this->getServer('HTTP_CLIENT_IP') != null) 
        {
            return $this->getServer('HTTP_CLIENT_IP');
        }
        
        if ($checkProxy && $this->getServer('HTTP_X_FORWARDED_FOR') != null) 
        {
            return $this->getServer('HTTP_X_FORWARDED_FOR');
        }
        
        return $this->getServer('REMOTE_ADDR');
    }
    
    
	public function setBaseUrl($baseUrl)
    {
    	!empty($baseUrl) && $this->_baseUrl = (string)$baseUrl;
    	return $this;
    }
    
    
    /**
     *
     * 获取baseUrl
     * @return string
     */
    public function getBaseUrl()
    {
    	if (!empty($this->_baseUrl)) return $this->_baseUrl;
    	
    	$filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : '';

        if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $filename)
        {
            $this->_baseUrl = $_SERVER['SCRIPT_NAME'];
        } 
        elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $filename) 
        {
            $this->_baseUrl = $_SERVER['PHP_SELF'];
        } 
        elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) 
        {
            $this->_baseUrl = $_SERVER['ORIG_SCRIPT_NAME'];
        } 
        else 
        {
            $path = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
            $file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
            $segs = explode('/', trim($file, '/'));
            $segs = array_reverse($segs);
            $index = 0;
            $last = count($segs);
            do 
            {
                $seg     = $segs[$index];
                $this->_baseUrl = '/' . $seg . $this->_baseUrl;
                ++$index;
            } 
            while (($last > $index) && (false !== ($pos = strpos($path, $this->_baseUrl))) && ($pos != 0));
        }

        $request_uri = $this->getRequestUri();

        if (strpos($request_uri, $this->_baseUrl) === 0) return $this->_baseUrl;

        if (strpos($request_uri, dirname($this->_baseUrl)) === 0) 
        {
            $this->_baseUrl = rtrim(dirname($this->_baseUrl), '/');
            return $this->_baseUrl;
        }

        $truncated_request_uri = $request_uri;
        if (($pos = strpos($request_uri, '?')) !== false) {
            $truncated_request_uri = substr($request_uri, 0, $pos);
        }

        $basename = basename($this->_baseUrl);
        if (empty($basename) || !strpos($truncated_request_uri, $basename)) {
            $this->_baseUrl = '';
            return $this->_baseUrl;
        }
        
        if ((strlen($request_uri) >= strlen($this->_baseUrl))
            && ((false !== ($pos = strpos($request_uri, $this->_baseUrl))) && ($pos !== 0)))
        {
            $this->_baseUrl = substr($request_uri, 0, $pos + strlen($this->_baseUrl));
        }
        
        $this->_baseUrl = rtrim($this->_baseUrl, '/');
        return $this->_baseUrl;
    }
    
    
    /**
     * 获取basePath
     *
	 * @access Public
     * @return String
     */
    public function getBasePath()
    {
    	if (!empty($this->_basePath)) return $this->_basePath;
    	
    	$filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : '';

        $base_url = $this->getBaseUrl();
        if (empty($base_url)) 
        {
            $this->_basePath = '';
            return $this->_basePath;
        }

        $this->_basePath = (basename($base_url) === $filename) ? dirname($base_url) : $base_url;

        if (substr(PHP_OS, 0, 3) === 'WIN') 
        {
            $this->_basePath = str_replace('\\', '/', $this->_basePath);
        }

        $this->_basePath = rtrim($this->_basePath, '/');
        return $this->_basePath;
    }
    
    
    /**
     * 获取PathInfo
     *
     * @access Public
     * @return String
     */
    public function getPathInfo()
    {
    	if (!empty($this->_pathInfo)) return $this->_pathInfo;
    	
    	$base_url = $this->getBaseUrl();
    	$request_uri = $this->getRequestUri();

        if ($request_uri == '') return '';

        if ($pos = strpos($request_uri, '?')) $request_uri = substr($request_uri, 0, $pos);
        
        if ($base_url !== null && ((!empty($base_url) && strpos($request_uri, $base_url) === 0) || empty($base_url)) && false === ($this->_pathInfo = substr($request_uri, strlen($base_url))))
        {  
            $this->_pathInfo = '';
        } 
        elseif ($base_url !== null || (!empty($base_url) && false === strpos($request_uri, $base_url))) 
        { 
            $this->_pathInfo = $request_uri; 
        }
        
        return $this->_pathInfo;
    }
    
    
    /**
     *
     * 获取RequestUri
     * @return string
     */
    public function getRequestUri()
    {
    	if (!empty($this->_requestUri)) return $this->_requestUri;
    	
        if (isset($_SERVER['HTTP_X_REWRITE_URL']))
        {
            $this->_requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
        }
        elseif (isset($_SERVER['IIS_WasUrlRewritten']) && $_SERVER['IIS_WasUrlRewritten'] == '1' && isset($_SERVER['UNENCODED_URL']) && $_SERVER['UNENCODED_URL'] != '') 
        {
            $this->_requestUri = $_SERVER['UNENCODED_URL'];
        } 
        elseif (isset($_SERVER['REQUEST_URI'])) 
        {
            $this->_requestUri = $_SERVER['REQUEST_URI'];
            $scheme_httphost = $this->getScheme() . '://' . $this->getHttpHost();
            if (strpos($this->_requestUri, $scheme_httphost) === 0) 
                $this->_requestUri = substr($this->_requestUri, strlen($scheme_httphost));
        } 
        elseif (isset($_SERVER['ORIG_PATH_INFO'])) 
        {
            $this->_requestUri = $_SERVER['ORIG_PATH_INFO'];
            if (!empty($_SERVER['QUERY_STRING'])) 
                $this->_requestUri .= '?' . $_SERVER['QUERY_STRING'];
        }
        else
        {
        	$this->_requestUri = '';
        }
        
        return $this->_requestUri;
    }
}
?>